/*-
 * Copyright (c) 2012-2013 Shang-Rong Cai. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $ MTBLAS: stblas.h    Rev. 0.0.19    2013-11-11T16:20+08:00 $
 */

#include <stddef.h>
#include <math.h>
#include <complex.h>

#ifndef STBLAS_H
#define STBLAS_H

#ifndef SIDX_TYPE
#define SIDX_TYPE
typedef long sidx_t;
#endif

#ifndef STEP_TYPE
#define STEP_TYPE
typedef long step_t;
#endif


/* stblas_1_dot.c */
extern int stblas_dotf(const size_t sz, const float *vx, const step_t incx, const float *vy, const step_t incy, float *rbuf);

extern int stblas_dot(const size_t sz, const double *vx, const step_t incx, const double *vy, const step_t incy, double *rbuf);

extern int stblas_dotl(const size_t sz, const long double *vx, const step_t incx, const long double *vy, const step_t incy, long double *rbuf);


extern int stblas_ucdotf(const size_t sz, const float complex *vx, const step_t incx, const float complex *vy, const step_t incy, float complex *rbuf);

extern int stblas_ucdot(const size_t sz, const double complex *vx, const step_t incx, const double complex *vy, const step_t incy, double complex *rbuf);

extern int stblas_ucdotl(const size_t sz, const long double complex *vx, const step_t incx, const long double complex *vy, const step_t incy, long double complex *rbuf);


extern int stblas_cdotf(const size_t sz, const float complex *vx, const step_t incx, const float complex *vy, const step_t incy, float complex *rbuf);

extern int stblas_cdot(const size_t sz, const double complex *vx, const step_t incx, const double complex *vy, const step_t incy, double complex *rbuf);

extern int stblas_cdotl(const size_t sz, const long double complex *vx, const step_t incx, const long double complex *vy, const step_t incy, long double complex *rbuf);


/* stblas_1_nrm.c */
extern int stblas_nrm2f(const size_t sz, const float *vx, const step_t incx, float *rbuf);

extern int stblas_nrm2(const size_t sz, const double *vx, const step_t incx, double *rbuf);

extern int stblas_nrm2l(const size_t sz, const long double *vx, const step_t incx, long double *rbuf);


extern int stblas_cnrm2f(const size_t sz, const float complex *vx, const step_t incx, float *rbuf);

extern int stblas_cnrm2(const size_t sz, const double complex *vx, const step_t incx, double *rbuf);

extern int stblas_cnrm2l(const size_t sz, const long double complex *vx, const step_t incx, long double *rbuf);


extern int stblas_asumf(const size_t sz, const float *vx, const step_t incx, float *rbuf);

extern int stblas_asum(const size_t sz, const double *vx, const step_t incx, double *rbuf);

extern int stblas_asuml(const size_t sz, const long double *vx, const step_t incx, long double *rbuf);


extern int stblas_casumf(const size_t sz, const float complex *vx, const step_t incx, float *rbuf);

extern int stblas_casum(const size_t sz, const double complex *vx, const step_t incx, double *rbuf);

extern int stblas_casuml(const size_t sz, const long double complex *vx, const step_t incx, long double *rbuf);


extern int stblas_iamaxf(const size_t sz, const float *vx, const step_t incx, sidx_t *rbuf);

extern int stblas_iamax(const size_t sz, const double *vx, const step_t incx, sidx_t *rbuf);

extern int stblas_iamaxl(const size_t sz, const long double *vx, const step_t incx, sidx_t *rbuf);


/* stblas_1_scp.c */
extern int stblas_swapf(const size_t sz, float *vx, const step_t incx, float *vy, const step_t incy);

extern int stblas_swap(const size_t sz, double *vx, const step_t incx, double *vy, const step_t incy);

extern int stblas_swapl(const size_t sz, long double *vx, const step_t incx, long double *vy, const step_t incy);


extern int stblas_cswapf(const size_t sz, float complex *vx, const step_t incx, float complex *vy, const step_t incy);

extern int stblas_cswap(const size_t sz, double complex *vx, const step_t incx, double complex *vy, const step_t incy);

extern int stblas_cswapl(const size_t sz, long double complex *vx, const step_t incx, long double complex *vy, const step_t incy);


extern int stblas_copyf(const size_t sz, const float *vx, const step_t incx, float *vy, const step_t incy);

extern int stblas_copy(const size_t sz, const double *vx, const step_t incx, double *vy, const step_t incy);

extern int stblas_copyl(const size_t sz, const long double *vx, const step_t incx, long double *vy, const step_t incy);


extern int stblas_ccopyf(const size_t sz, const float complex *vx, const step_t incx, float complex *vy, const step_t incy);

extern int stblas_ccopy(const size_t sz, const double complex *vx, const step_t incx, double complex *vy, const step_t incy);

extern int stblas_ccopyl(const size_t sz, const long double complex *vx, const step_t incx, long double complex *vy, const step_t incy);


extern int stblas_axpyf(const size_t sz, const float alpha, const float *vx, const step_t incx, float *vy, const step_t incy);

extern int stblas_axpy(const size_t sz, const double alpha, const double *vx, const step_t incx, double *vy, const step_t incy);

extern int stblas_axpyl(const size_t sz, const long double alpha, const long double *vx, const step_t incx, long double *vy, const step_t incy);


extern int stblas_caxpyf(const size_t sz, const float complex alpha, const float complex *vx, const step_t incx, float complex *vy, const step_t incy);

extern int stblas_caxpy(const size_t sz, const double complex alpha, const double complex *vx, const step_t incx, double complex *vy, const step_t incy);

extern int stblas_caxpyl(const size_t sz, const long double complex alpha, const long double complex *vx, const step_t incx, long double complex *vy, const step_t incy);


extern int stblas_scalf(const size_t sz, const float alpha, float *vx, const step_t incx);

extern int stblas_scal(const size_t sz, const double alpha, double *vx, const step_t incx);

extern int stblas_scall(const size_t sz, const long double alpha, long double *vx, const step_t incx);


extern int stblas_cscalf(const size_t sz, const float complex alpha, float complex *vx, const step_t incx);

extern int stblas_cscal(const size_t sz, const double complex alpha, double complex *vx, const step_t incx);

extern int stblas_cscall(const size_t sz, const long double complex alpha, long double complex *vx, const step_t incx);


extern int stblas_fcscalf(const size_t sz, const float alpha, float complex *vx, const step_t incx);

extern int stblas_fcscal(const size_t sz, const double alpha, double complex *vx, const step_t incx);

extern int stblas_fcscall(const size_t sz, const long double alpha, long double complex *vx, const step_t incx);


#ifndef BLAS_FLAGS
#define BLAS_FLAGS
#define MTBLAS_ROW_MAJOR   101
#define MTBLAS_COL_MAJOR   102

#define MTBLAS_TRANS_NONE  111
#define MTBLAS_TRANS       112
#define MTBLAS_TRANS_CONJ  113

#define MTBLAS_UPLO_UPPER  121
#define MTBLAS_UPLO_LOWER  122

#define MTBLAS_DIAG_NONE   131
#define MTBLAS_DIAG_UNIT   132

#define MTBLAS_SIDE_LEFT   141
#define MTBLAS_SIDE_RIGHT  142
#endif


/* stblas_2_gmv.c */
extern int stblas_gemvf(const int rdr, const int trn, const size_t rz, const size_t cz, const float alpha, const float *ma, const size_t lda, const float *vx, const step_t incx, const float beta, float *vy, const step_t incy);

extern int stblas_gemv(const int rdr, const int trn, const size_t rz, const size_t cz, const double alpha, const double *ma, const size_t lda, const double *vx, const step_t incx, const double beta, double *vy, const step_t incy);

extern int stblas_gemvl(const int rdr, const int trn, const size_t rz, const size_t cz, const long double alpha, const long double *ma, const size_t lda, const long double *vx, const step_t incx, const long double beta, long double *vy, const step_t incy);


extern int stblas_cgemvf(const int rdr, const int trn, const size_t rz, const size_t cz, const float complex alpha, const float complex *ma, const size_t lda, const float complex *vx, const step_t incx, const float complex beta, float complex *vy, const step_t incy);

extern int stblas_cgemv(const int rdr, const int trn, const size_t rz, const size_t cz, const double complex alpha, const double complex *ma, const size_t lda, const double complex *vx, const step_t incx, const double complex beta, double complex *vy, const step_t incy);

extern int stblas_cgemvl(const int rdr, const int trn, const size_t rz, const size_t cz, const long double complex alpha, const long double complex *ma, const size_t lda, const long double complex *vx, const step_t incx, const long double complex beta, long double complex *vy, const step_t incy);


/* stblas_3_gmm.c */
/* A = alpha A */
extern int stblas_2e_mxselfscalf(const int rdr, const size_t rz, const size_t cz, const float alpha, const float *ma, const size_t lda);

extern int stblas_2e_mxselfscal(const int rdr, const size_t rz, const size_t cz, const double alpha, const double *ma, const size_t lda);

extern int stblas_2e_mxselfscall(const int rdr, const size_t rz, const size_t cz, const long double alpha, const long double *ma, const size_t lda);


extern int stblas_2e_cmxselfscalf(const int rdr, const size_t rz, const size_t cz, const float complex alpha, const float complex *ma, const size_t lda);

extern int stblas_2e_cmxselfscal(const int rdr, const size_t rz, const size_t cz, const double complex alpha, const double complex *ma, const size_t lda);

extern int stblas_2e_cmxselfscall(const int rdr, const size_t rz, const size_t cz, const long double complex alpha, const long double complex *ma, const size_t lda);


/* C = A * B + C */
extern int stblas_3e_mxmxmulaccf(const int rdr, const int trna, const int trnb, const size_t rz, const size_t cz, const size_t kz, const float *ma, const size_t lda, const float *mb, const size_t ldb, float *mc, const size_t ldc);

extern int stblas_3e_mxmxmulacc(const int rdr, const int trna, const int trnb, const size_t rz, const size_t cz, const size_t kz, const double *ma, const size_t lda, const double *mb, const size_t ldb, double *mc, const size_t ldc);

extern int stblas_3e_mxmxmulaccl(const int rdr, const int trna, const int trnb, const size_t rz, const size_t cz, const size_t kz, const long double *ma, const size_t lda, const long double *mb, const size_t ldb, long double *mc, const size_t ldc);


extern int stblas_3e_cmxmxmulaccf(const int rdr, const int trna, const int trnb, const size_t rz, const size_t cz, const size_t kz, const float complex *ma, const size_t lda, const float complex *mb, const size_t ldb, float complex *mc, const size_t ldc);

extern int stblas_3e_cmxmxmulacc(const int rdr, const int trna, const int trnb, const size_t rz, const size_t cz, const size_t kz, const double complex *ma, const size_t lda, const double complex *mb, const size_t ldb, double complex *mc, const size_t ldc);

extern int stblas_3e_cmxmxmulaccl(const int rdr, const int trna, const int trnb, const size_t rz, const size_t cz, const size_t kz, const long double complex *ma, const size_t lda, const long double complex *mb, const size_t ldb, double long complex *mc, const size_t ldc);

/* C = alpah A * B + beta * C */
extern int stblas_gemmf(const int rdr, const int trna, const int trnb, const size_t rz, const size_t cz, const size_t kz, const float alpha, const float *ma, const size_t lda, const float *mb, const size_t ldb, const float beta, float *mc, const size_t ldc);

extern int stblas_gemm(const int rdr, const int trna, const int trnb, const size_t rz, const size_t cz, const size_t kz, const double alpha, const double *ma, const size_t lda, const double *mb, const size_t ldb, const double beta, double *mc, const size_t ldc);

extern int stblas_gemml(const int rdr, const int trna, const int trnb, const size_t rz, const size_t cz, const size_t kz, const long double alpha, const long double *ma, const size_t lda, const long double *mb, const size_t ldb, const long double beta, long double *mc, const size_t ldc);


extern int stblas_cgemmf(const int rdr, const int trna, const int trnb, const size_t rz, const size_t cz, const size_t kz, const float complex alpha, const float complex *ma, const size_t lda, const float complex *mb, const size_t ldb, const float complex beta, float complex *mc, const size_t ldc);

extern int stblas_cgemm(const int rdr, const int trna, const int trnb, const size_t rz, const size_t cz, const size_t kz, const double complex alpha, const double complex *ma, const size_t lda, const double complex *mb, const size_t ldb, const double complex beta, double complex *mc, const size_t ldc);

extern int stblas_cgemml(const int rdr, const int trna, const int trnb, const size_t rz, const size_t cz, const size_t kz, const long double complex alpha, const long double complex *ma, const size_t lda, const long double complex *mb, const size_t ldb, const long double complex beta, long double complex *mc, const size_t ldc);

#endif
